﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Text.Json;
using System.Threading.Tasks;
using Dark_Core_Library.UniModules.Models;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;

namespace Dark_Core_Library.NetworkModules.HTTP
{
    /// <summary>
    /// 通用HTTP帮助类
    /// </summary>
    public static class UniHttpHelper
    {

        public record DataArrResponse<Sender>(int Total,int Subtotal, Sender Data) where Sender : ICollection;

        /// <summary>
        /// 将数组数据转换至通用响应
        /// </summary>
        /// <param name="data">数据源</param>
        /// <param name="msg">消息</param>
        /// <param name="responseStatus">响应状态</param>
        /// <param name="total">总数据条数</param>
        /// <returns></returns>
        public static UniHttpResponse<DataArrResponse<TSender>> ToUniHttpArrResponse<TSender>(this TSender data,string? msg = null, int? total = null,UniHttpResponseStatus responseStatus = UniHttpResponseStatus.Success)
        where TSender  : ICollection
        { 
            DataArrResponse<TSender> dataResult = new(total ?? data.Count, data.Count, data);
            UniHttpResponse<DataArrResponse<TSender>> result = UniHttpResponse<DataArrResponse<TSender>>.CreateInstance(msg??"请求成功",dataResult,responseStatus);
            return result;
        }

        /// <summary>
        /// 将数据转换至通用响应
        /// </summary>
        /// <param name="data">数据源</param>
        /// <param name="msg">消息</param>
        /// <param name="responseStatus">响应状态</param>
        /// <returns>通用响应对象</returns>
        public static UniHttpResponse<TSender> ToUniHttpResponse<TSender>(this TSender data, string? msg = null,
            UniHttpResponseStatus responseStatus = UniHttpResponseStatus.Success)
            where TSender : class => UniHttpResponse<TSender>.CreateInstance(msg??"请求成功", data, responseStatus);

        /// <summary>
        /// 将操作结果转换至通用响应
        /// </summary>
        /// <typeparam name="TSender">操作源类型</typeparam>
        /// <typeparam name="TResult">操作结果类型</typeparam>
        /// <param name="operationResult">操作结果对象</param>
        /// <returns>通用相应对象</returns>
        public static UniHttpResponse<TResult> ToUniHttpResponse<TSender,TResult>(this UniOperationResult<TSender,TResult> operationResult) 
        => UniHttpResponse<TResult>.CreateInstance(operationResult.Message,operationResult.Result,operationResult.IsSuccess?UniHttpResponseStatus.Success:UniHttpResponseStatus.Error);



        /// <summary>
        /// 是否包含所需请求参数
        /// </summary>
        /// <param name="request">请求</param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static UniOperationResult<UniHttpRequest, string[]> Contains(this UniHttpRequest request, params string[] args)
        {
            if (request.args == null) return request.ToOperationResult(Array.Empty<string>(), "请求参数为空",false);
            var set = new HashSet<string>(request.args.Keys);
            bool isAllContains = args.All(set.Contains);
            var missingArgs = args.Where(x => !set.Contains(x)).ToList();

            return request.ToOperationResult(missingArgs.ToArray(), !isAllContains?$"请求参数缺少：{string.Join("|",missingArgs.ToArray())}":"请求参数包含全部参数", isAllContains);
        }


        /// <summary>
        /// 尝试安全获取请求参数值（支持 JSON 反序列化）
        /// </summary>
        public static UniOperationResult<UniHttpRequest, string> TryGetValue<TResult>(
            this UniHttpRequest request,
            string key,
            out TResult value,
            TResult defaultValue = default)
        {
            value = defaultValue;


            
            // 参数基础校验
            if (request.args == null || !request.args.TryGetValue(key, out var rawValue))
            {
                return request.ToOperationResult(key, "请求参数集合为空或缺少指定键", false);
            }

            // 处理 JSON 特殊类型（System.Text.Json.JsonElement）
            if (rawValue is JsonElement jsonElement)
            {
                return HandleJsonElement(request, key, jsonElement, out value);
            }

            // 处理普通类型转换
            try
            {
                // 空字符串特殊处理
                if (rawValue is string strValue && string.IsNullOrWhiteSpace(strValue))
                {
                    return request.ToOperationResult(key, "参数值为空字符串", false);
                }

                value = (TResult)Convert.ChangeType(rawValue, typeof(TResult));
                if (value == null) value = defaultValue; ;
                return request.ToOperationResult(key, "参数获取成功", true);
            }
            catch (InvalidCastException ex)
            {
                return request.ToOperationResult(key, $"类型转换失败: {ex.Message}", false);
            }
        }

        /// <summary>
        /// 处理 JSON 元素的反序列化
        /// </summary>
        private static UniOperationResult<UniHttpRequest, string> HandleJsonElement<TResult>(
            UniHttpRequest request,
            string key,
            JsonElement jsonElement,
            out TResult value)
        {
            value = default;

            try
            {
                // 处理 JSON null 值
                if (jsonElement.ValueKind == JsonValueKind.Null)
                {
                    return request.ToOperationResult(key, "JSON 参数值为 null", false);
                }

                // 根据目标类型反序列化
                var options = new JsonSerializerOptions();
                options.PropertyNameCaseInsensitive = true;
                options.Converters.Add(new JsonStringEnumConverter());
                var tValue =  jsonElement.Deserialize<TResult>(options);

                value = tValue ?? default;

                // 空字符串二次校验
                if (value is string str && string.IsNullOrWhiteSpace(str))
                {
                    value = default;
                    return request.ToOperationResult(key, "反序列化后字符串为空", false);
                }

                return request.ToOperationResult(key, "JSON 参数解析成功", true);
            }
            catch (JsonException ex)
            {
                return request.ToOperationResult(key, $"JSON 反序列化失败: {ex.Message}", false);
            }
        }

    }
}
